package service

import (
	"miaoyu/internal/model"
	"net/http"
	"reflect"

	"github.com/gogf/gf/v2/encoding/ghtml"

	"github.com/gogf/gf/v2/frame/g"

	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/net/ghttp"
)

type middlewareService struct{}

func sanitizeStruct(v reflect.Value) {
	switch v.Kind() {
	case reflect.Ptr:
		if !v.IsNil() {
			sanitizeStruct(v.Elem())
		}
	case reflect.Struct:
		for i := 0; i < v.NumField(); i++ {
			sanitizeStruct(v.Field(i))
		}
	case reflect.Slice, reflect.Array:
		for i := 0; i < v.Len(); i++ {
			sanitizeStruct(v.Index(i))
		}
	case reflect.Map:
		for _, key := range v.MapKeys() {
			sanitizeStruct(v.MapIndex(key))
		}
	case reflect.String:
		v.SetString(ghtml.SpecialChars(v.String()))
	}
}
func XssMiddleware(r *ghttp.Request) {
	for k, v := range r.GetMap() {
		switch v.(type) {
		case string:
			r.SetParam(k, ghtml.SpecialChars(v.(string)))
		default:
			sanitizeStruct(reflect.ValueOf(v))
		}
	}
	r.Middleware.Next()
}

var middleware = middlewareService{}

func Middleware() *middlewareService {
	return &middleware
}

// MiddlewareDefaultResponse is the default middleware handling handler response object and its error.
func MiddlewareDefaultResponse(r *ghttp.Request) {
	r.Middleware.Next()

	// There's custom buffer content, it then exits current handler.
	if r.Response.BufferLength() > 0 {
		return
	}

	var (
		msg  string
		err  = r.GetError()
		code = gerror.Code(err)
	)
	if err != nil {
		if code == gcode.CodeNil {
			code = gcode.CodeInternalError
		}
		msg = err.Error()
	} else if r.Response.Status > 0 && r.Response.Status != http.StatusOK {
		msg = http.StatusText(r.Response.Status)
		switch r.Response.Status {
		case http.StatusNotFound:
			code = gcode.CodeNotFound
		case http.StatusForbidden:
			code = gcode.CodeNotAuthorized
		default:
			code = gcode.CodeUnknown
		}
	} else {
		code = gcode.CodeOK
	}
	internalErr := JsonResp().CommonResp(r)
	internalErr.SetError(msg)
	internalErr.WriteJson()

}

func (s *middlewareService) CORS(r *ghttp.Request) {
	r.Response.CORSDefault()
	r.Middleware.Next()
}

// Auth jwt 登录验证中间件
func (s *middlewareService) Auth(r *ghttp.Request) {
	Auth().MiddlewareFunc()(r)

	r.Middleware.Next()
}

// Access casbin权限验证中间件
func (s *middlewareService) Access(r *ghttp.Request) {
	Access().MiddleWareFunc(r)
	r.Middleware.Next()
}

// Ctx 自定义上下文对象*********************
func (s *middlewareService) Ctx(r *ghttp.Request) {
	//if !r.IsFileRequest() {
	//	//fmt.Println("请求表单")
	//}
	// 初始化，务必最开始执行
	customCtx := &model.Context{
		Session: r.Session,
		Data:    make(g.Map),
	}
	BizCtx().Init(r, customCtx)

	// 将自定义的上下文对象传递到模板变量中使用
	r.Assigns(g.Map{
		"Context": customCtx,
	})

	// 执行下一步请求逻辑
	r.Middleware.Next()
}
func (s *middlewareService) Log(r *ghttp.Request) {

	Log().MiddleWareFunc(r)
}
func (s *middlewareService) CmsAuth(r *ghttp.Request) {

	//CmsAuth().MiddleWareFunc(r)

}
func (s *middlewareService) OauthAuth(r *ghttp.Request) {
	OauthAuth().MiddlewareFunc()(r)

	r.Middleware.Next()
}
